<template>
  <div class="app-container">
    <!-- 1. 选择文件夹 -->
    <div style="display:flex;gap:20px;align-items:flex-start;">
      <div class="file-select theory-file-select">
        <el-card>
          <div slot="header" class="clearfix">
            <span>选择理论文件夹</span>
          </div>
          <div class="file-dropzone" @click="triggerInput('theory')">
            <i class="el-icon-folder"></i>
            <div class="el-upload__text">点击选择理论文件夹</div>
            <div v-if="theoryFiles.length" class="el-upload__tip">{{ theoryFiles.length }} 个文件</div>
          </div>
          <input type="file" webkitdirectory directory @change="handleFileChange($event, 'theory')" style="display:none;" ref="theoryInput" />
        </el-card>
      </div>

      <div class="file-select actual-file-select">
        <el-card>
          <div slot="header" class="clearfix">
            <span>选择实际文件夹</span>
          </div>
          <div class="file-dropzone" @click="triggerInput('actual')">
            <i class="el-icon-folder"></i>
            <div class="el-upload__text">点击选择实际文件夹</div>
            <div v-if="actualFiles.length" class="el-upload__tip">{{ actualFiles.length }} 个文件</div>
          </div>
          <input type="file" webkitdirectory directory @change="handleFileChange($event, 'actual')" style="display:none;" ref="actualInput" />
        </el-card>
      </div>

      <!-- 参数 & 按钮 -->
      <div style="display:flex;align-items:center;gap:20px;margin-left:40px;">
        <div>
          <label>坐标差值(mm)：</label>
          <el-select v-model="tolerance" style="width:90px;">
            <el-option v-for="n in tolerances" :key="n" :label="n" :value="n" />
          </el-select>
        </div>

        <div>
          <label>坐标数：</label>
          <el-select v-model="paramCount" style="width:90px;">
            <el-option v-for="n in paramCounts" :key="n" :label="n" :value="n" />
          </el-select>
        </div>

        <el-button type="primary" :disabled="!canCompare" @click="compareFolders">
          开始对比
        </el-button>
      </div>
    </div>

    <el-collapse v-if="summaryAll.length" style="margin-top:20px">
      <el-collapse-item title="总览 - 全部焊点">
        <el-table :data="summaryAll" border stripe>
          <el-table-column prop="robot" label="文件名" width="300" />
          <el-table-column prop="total" label="总行数" width="100" />
          <el-table-column prop="same" label="一致行数" width="100" />
          <el-table-column prop="rate" label="匹配率" width="100" />
        </el-table>
      </el-collapse-item>
    </el-collapse>

    <el-collapse v-if="summaryKey.length" style="margin-top:20px">
      <el-collapse-item title="总览 - 关键焊点">
        <el-table :data="summaryKey" border stripe>
          <el-table-column prop="robot" label="文件名" width="300" />
          <el-table-column prop="total" label="总行数" width="100" />
          <el-table-column prop="same" label="一致行数" width="100" />
          <el-table-column prop="rate" label="匹配率" width="100" />
        </el-table>
      </el-collapse-item>
    </el-collapse>

    <el-collapse v-if="Object.keys(detailAll).length" style="margin-top:20px">
      <el-collapse-item title="详细对比 - 全部焊点">
        <el-collapse>
          <el-collapse-item v-for="(rows, fileName) in detailAll" :key="fileName" :title="fileName">
            <el-table :data="rows" stripe>
              <el-table-column prop="id" label="编号" width="120" />
              <el-table-column prop="oldStr" label="理论(x,y,z)" />
              <el-table-column prop="newStr" label="实际(x,y,z)" />
              <el-table-column prop="same" label="是否一致" width="100">
                <template #default="scope">
                  <el-tag :type="scope.row.same ? 'success' : 'danger'">
                    {{ scope.row.same ? '是' : '否' }}
                  </el-tag>
                </template>
              </el-table-column>
            </el-table>
          </el-collapse-item>
        </el-collapse>
      </el-collapse-item>
    </el-collapse>

    <el-collapse v-if="Object.keys(detailKey).length" style="margin-top:20px">
      <el-collapse-item title="详细对比 - 关键焊点">
        <el-collapse>
          <el-collapse-item v-for="(rows, fileName) in detailKey" :key="fileName" :title="fileName">
            <el-table :data="rows" stripe>
              <el-table-column prop="id" label="编号" width="120" />
              <el-table-column prop="oldStr" label="理论(x,y,z)" />
              <el-table-column prop="newStr" label="实际(x,y,z)" />
              <el-table-column prop="same" label="是否一致" width="100">
                <template #default="scope">
                  <el-tag :type="scope.row.same ? 'success' : 'danger'">
                    {{ scope.row.same ? '是' : '否' }}
                  </el-tag>
                </template>
              </el-table-column>
            </el-table>
          </el-collapse-item>
        </el-collapse>
      </el-collapse-item>
    </el-collapse>

    <div style="margin-top:20px">
      <el-button v-if="Object.keys(detailAll).length" type="primary" @click="Dump('全部')">
        导出全部焊点 Excel
      </el-button>
      <el-button v-if="Object.keys(detailKey).length" type="primary" @click="Dump('关键')">
        导出关键焊点 Excel
      </el-button>
    </div>

    <el-dialog :title="Export.title" :visible.sync="Export.open" width="400px" append-to-body>
      <el-input v-model="Export.fileName" placeholder="请输入文件名，无需后缀" />
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="confirmExport">确 定</el-button>
        <el-button @click="Export.open = false">取 消</el-button>
      </div>
    </el-dialog>

  </div>
</template>

<script>
import ExcelJS from 'exceljs'
import { compareCoordinate } from '@/api/compareCoordinate/compareCoordinate'

export default {
  name: 'FolderCompare',
  data() {
    return {
      tolerance: 10,
      tolerances: [5, 6, 7, 8, 9, 10, 15, 20],
      paramCount: 3,
      paramCounts: [2, 3, 6],
      theoryFiles: [],
      actualFiles: [],
      summaryAll: [],
      summaryKey: [],
      detailAll: {},
      detailKey: {},
      // 导出参数
      Export:{
        // // 是否显示弹出层
        open: false,
        // // 弹出层标题
        title: "",
        type: '',         // 记录当前要导出的是“全部”还是“关键”
        fileName: ''      // 用户输入的文件名
      },
    }
  },
  computed: {
    canCompare() {
      return this.theoryFiles.length && this.actualFiles.length
    }
  },
  methods: {
    /* 点击选择文件夹 */
    triggerInput(type) {
      this.$refs[type === 'theory' ? 'theoryInput' : 'actualInput'].click()
    },
    handleFileChange(e, type) {
      this[type === 'theory' ? 'theoryFiles' : 'actualFiles'] = [...e.target.files].filter(f => f.name.toLowerCase().endsWith('.jbi'))
      e.target.value = '' // 允许重复选同文件夹
    },
    async compareFolders() {
      if (!this.canCompare) return
      const formData = new FormData()
      this.theoryFiles.forEach(f => formData.append('theoryFiles', f))
      this.actualFiles.forEach(f => formData.append('actualFiles', f))
      formData.append('tolerance', this.tolerance)
      formData.append('paramCount', this.paramCount)

      try {
        const { data , msg} = await compareCoordinate(formData)
        this.buildData(data)
        this.$message.success(msg || '对比完成！')
      } catch (e) {
        const { response } = e
        // 先打印看结构
        console.log('response.data =', response?.data)

        if (response?.data?.unmatchedFiles) {
          const list = response.data.unmatchedFiles
            .map(f => `<li style="margin:4px 0">${f}</li>`)
            .join('')
          this.$alert(
            `<div>以下文件出现错误：<ul style="margin:0;padding-left:20px">${list}</ul></div>`,
            '文件未匹配',
            { dangerouslyUseHTMLString: true, type: 'warning' }
          )
        } else {
          // 兜底
          this.$message.error('对比失败：' + (response?.data?.msg || e.message || '未知'))
        }
        this.reset()
      }
    },
    buildData(data) {
      this.summaryAll = []
      this.summaryKey = []
      this.detailAll = {}
      this.detailKey = {}
      Object.keys(data).forEach(fileName => {
        const d = data[fileName]
        if (d['全部']) {
          const r = d['全部'].ratio || {}
          this.summaryAll.push({
            robot: fileName,
            total: r.total || 0,
            same: r.same || 0,
            rate: ((r.rate || 0) * 100).toFixed(2)
          })
          this.detailAll[fileName] = d['全部'].detail
        }
        if (d['关键']) {
          const r = d['关键'].ratio || {}
          this.summaryKey.push({
            robot: fileName,
            total: r.total || 0,
            same: r.same || 0,
            rate: ((r.rate || 0) * 100).toFixed(2)
          })
          this.detailKey[fileName] = d['关键'].detail
        }
      })
    },

    Dump(type) {
      this.Export.type = type;
      this.Export.title = `导出${type}焊点 Excel`;
      this.Export.fileName = `坐标对比_${type}`;   // 默认文件名
      this.Export.open = true;

    },
    confirmExport() {
      const type = this.Export.type
      const fileName = this.Export.fileName.trim() || `坐标对比_${type}`
      this.downloadExcel(type, fileName)
      this.Export.open = false
    },
    async downloadExcel(type, fileName = `坐标对比_${type}`) {
      try {
        const wb = new ExcelJS.Workbook()
        const src = type === '全部' ? this.detailAll : this.detailKey
        const sum = type === '全部' ? this.summaryAll : this.summaryKey
        const ws1 = wb.addWorksheet(`总览-${type}`)
        ws1.columns = [
          {header: '文件名', key: 'robot', width: 30},
          {header: '总行数', key: 'total', width: 12},
          {header: '一致行数', key: 'same', width: 12},
          {header: '匹配率', key: 'rate', width: 12}
        ]
        sum.forEach(r => {
          const row = ws1.addRow(r)
          if (Number(r.rate) < 85) {
            const lastCell = row.getCell(row.cellCount)
            lastCell.fill = {
              type: 'pattern', pattern: 'solid', fgColor: {argb: 'FFFF0000'}
            };
          }
        })
        Object.entries(src).forEach(([fileName, rows]) => {
          const isKey = type === '关键';
          const ws = wb.addWorksheet(`${fileName}-${type}`);

          const theory = ['X','Y','Z'].slice(0,this.paramCount).map(a=>
            ({ header:'理论 '+a, key:'old'+a, width:10 }));
          const actual = ['X','Y','Z'].slice(0,this.paramCount).map(a=>
            ({ header:'实际 '+a, key:'new'+a, width:10 }));
          const dev    = ['X','Y','Z'].slice(0,this.paramCount).map(a=>
            ({ header:'偏差 '+a, key:a,        width:10 }));
          ws.columns = [
            { header:'编号', key:'id', width:15 },
            ...theory,          // 理论 X、Y、Z
            ...actual,          // 实际 X、Y、Z
            ...dev,             // 偏差 X、Y、Z
            ...(isKey ? [
              { header:'WTM1', key:'wtm1', width:10 },
              { header:'WTM2', key:'wtm2', width:10 }
            ] : []),
            { header:'是否一致', key:'same', width:5 }
          ];

          rows.forEach(r => {
            const oldXYZ = r.oldStr.split(',').map(v => parseFloat(v));
            const newXYZ = r.newStr.split(',').map(v => parseFloat(v));
            const rowData = { id: r.id };
            'xyz'.slice(0,this.paramCount).split('').forEach((axis, i) => {
              rowData[`old${axis.toUpperCase()}`] = oldXYZ [i]?.toFixed(3) ?? '0.000';
              rowData[`new${axis.toUpperCase()}`] = newXYZ [i]?.toFixed(3) ?? '0.000';
              rowData[axis.toUpperCase()] = r[axis].toFixed(3);
            })
            Object.assign(rowData, {
              ...(isKey ? { wtm1: r.wtm1 || '', wtm2: r.wtm2 || '' } : {}),
              same: r.same ? '✔' : '✘'
            });
            const row = ws.addRow(rowData);
            if(Math.abs(r.x ) > this.tolerance)
              row.getCell('X').fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFFF0000' } };
            if(this.paramCount > 1 && Math.abs(r.y ) > this.tolerance)
              row.getCell('Y').fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFFF0000' } };
            if(this.paramCount > 2 && Math.abs(r.z ) > this.tolerance)
              row.getCell('Z').fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FFFF0000' } };
            if (!r.same) {
              const lastCell = row.getCell(row.cellCount)
              lastCell.fill = {
                type: 'pattern', pattern: 'solid', fgColor: {argb: 'FFFF0000'}
              };
            }
          })
        })
        // 2. 空两行
        ws1.addRow([]);
        ws1.addRow([]);

        // 3. 计算统计值
        const totalFiles = sum.length;
        const qualifiedCnt = sum.filter(r => Number(r.rate) >= 85).length;
        const avgRate1 = totalFiles ? (qualifiedCnt / totalFiles) * 100 : 0;
        const totalWelds = sum.reduce((s, r) => s + Number(r.total), 0);
        const qualifiedWelds = sum.reduce((s, r) => s + Number(r.same), 0);
        const avgRate2 = totalFiles ? (sum.reduce((s, r) => s + Number(r.rate), 0) / totalFiles).toFixed(2) : 0;

        // 4. 追加统计行
        ws1.addRow({robot: '总机器人数', total: totalFiles, same: '', rate: ''});
        ws1.addRow({robot: '85%及以上的符合数', total: qualifiedCnt, same: '', rate: ''});
        ws1.addRow({robot: '85%及以上的符合率', total: '', same: '', rate: avgRate1 + '%'});
        ws1.addRow({robot: '总焊点数', total: totalWelds, same: '', rate: ''});
        ws1.addRow({robot: '总焊点符合数', total: qualifiedWelds, same: '', rate: ''});
        ws1.addRow({robot: '焊点符合率', total: '', same: '', rate: avgRate2 + '%'});

        // 5. 加粗并居中
        [ws1.lastRow.number - 5, ws1.lastRow.number - 4, ws1.lastRow.number - 3, ws1.lastRow.number - 2, ws1.lastRow.number - 1, ws1.lastRow.number].forEach(rn => {
          const row = ws1.getRow(rn);
          row.eachCell(cell => {
            cell.font = {bold: true};
            cell.alignment = {vertical: 'middle', horizontal: 'center'};
          });
        });

        const buffer = await wb.xlsx.writeBuffer()
        saveAs(new Blob([buffer]), `${fileName}.xlsx`)
      } catch (err) {
        console.error(err);                 // 控制台
        this.$message.error('导出失败：' + (err.message || '未知错误'));
      }
    },
    reset() {
      this.summaryAll = []
      this.summaryKey = []
      this.detailAll = {}
      this.detailKey = {}
    }
  }
}
</script>

<style scoped>
.app-container {
  padding: 20px;
}

.file-select {
  width: 300px;
}

.file-dropzone {
  border: 2px dashed #d9d9d9;
  border-radius: 6px;
  padding: 20px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.3s;
}

.file-dropzone:hover {
  border-color: #409EFF;
}

.el-upload__tip {
  color: #999;
  font-size: 12px;
}

/* 理论文件夹的样式 */
.theory-file-select .file-dropzone {
  background-color: #f0f9eb; /* 浅绿色背景 */
  border-color: #7cc67c; /* 绿色边框 */
  color: #333; /* 深灰色文字 */
}

.theory-file-select .file-dropzone:hover {
  border-color: #409EFF; /* 鼠标悬停时的边框颜色 */
}

/* 实际文件夹的样式 */
.actual-file-select .file-dropzone {
  background-color: #fdf6ec; /* 浅黄色背景 */
  border-color: #f5dab1; /* 橙色边框 */
  color: #333; /* 深灰色文字 */
}

.actual-file-select .file-dropzone:hover {
  border-color: #409EFF; /* 鼠标悬停时的边框颜色 */
}
</style>
